package com.infore.qualityControl.service.impl;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.infore.qualityControl.enums.QualityProjectEnum;
import com.infore.qualityControl.enums.QualitySpecificationEnum;
import com.infore.qualityControl.po.Recovery;
import com.infore.qualityControl.po.SpanDrift;
import com.infore.qualityControl.po.VerificationOfStandardSample;
import com.infore.qualityControl.po.ZeroDrift;
import com.infore.qualityControl.remoteEntity.CheckData;
import com.infore.qualityControl.remoteEntity.RecoveryData;
import com.infore.qualityControl.remoteEntity.SpanCheckData;
import com.infore.qualityControl.remoteEntity.ZeroCheckData;
import com.infore.qualityControl.remoteService.IDataReceivingService;
import com.infore.qualityControl.remoteService.ISiteManageService;
import com.infore.qualityControl.repository.IRecoveryRepository;
import com.infore.qualityControl.repository.ISpanDriftRepository;
import com.infore.qualityControl.repository.IVerificationOfStandardSampleRepository;
import com.infore.qualityControl.repository.IZeroDriftRepository;
import com.infore.qualityControl.select.dto.QueryParamDto;
import com.infore.qualityControl.service.ICreateQualityDataService;
import com.infore.qualityControl.service.IQualityControlSetService;
import com.infore.qualityControl.util.DateUtil;
import com.infore.qualityControl.util.JsonUtils;
import com.infore.qualityControl.util.ObjectMapperUtil;
import com.infore.qualityControl.util.QualityDataUtil;
import com.infore.qualityControl.util.RedisUtil;
import com.infore.qualityControl.util.ResultEntity;

@Service
public class CreateQualityDataServiceImpl implements ICreateQualityDataService {
	
	private static final Logger logger = LoggerFactory.getLogger(CreateQualityDataServiceImpl.class);
	
	@Autowired
	IDataReceivingService IDataReceivingService;

	@Autowired
	ISiteManageService ISiteManageService;

	@Autowired
	IQualityControlSetService IQualityControlSetService;

	@Autowired
	ObjectMapperUtil objectMapperUtil;

	@Autowired
	RedisUtil RedisUtil;

	@Autowired
	IZeroDriftRepository iZeroDriftRepository;

	@Autowired
	ISpanDriftRepository iSpanDriftRepository;

	@Autowired
	IRecoveryRepository iRecoveryRepository;

	@Autowired
	IVerificationOfStandardSampleRepository iVerificationOfStandardSampleRepository;

	public static final String QUALIFIED = "合格";
	public static final String NO_QUALIFIED = "不合格";
	public static final String DATA_FLAG = "N";
	public static final String FLAG = "-";

	@SuppressWarnings("unchecked")
	@Override
	public void createZeroCheckData(String factorCode) {
		ResultEntity resultEntity = IDataReceivingService.queryZeroCheckData(factorCode);
		if (resultEntity.getCode() == 1) {
			System.out.println("获取零点核查初始数据失败！");
		}
		List<ZeroCheckData> list = objectMapperUtil.convertList(resultEntity, ZeroCheckData.class);
		// 先封装因子+时间,测定值的数据结构，存值
		Map<String, Object> indexTimeMap = new HashMap<String, Object>();
		// 获取缓存数据
		Date endDate = new Date();
		Date startDate = DateUtil.addHour(endDate, -48);
		Object redisList = RedisUtil.get("zeroValueMap");
		Map<String, Object> valueMap = new HashMap<String, Object>();
		if (redisList != null) {
			valueMap = (Map<String, Object>) redisList;
		} else {// 如果缓存为空则从数据库查询前一天数据
			List<ZeroDrift> listZero = iZeroDriftRepository.findByTimeBetweenOrderByTimeDesc(startDate, endDate);
			for (ZeroDrift zeroDrift : listZero) {
				Double mapValue = zeroDrift.getValue() == null ? null
						: QualityDataUtil.scaleData(zeroDrift.getIndexCode(), Double.valueOf(zeroDrift.getValue()));
				valueMap.put(
						zeroDrift.getStationCode() + zeroDrift.getIndexCode() + "_"
								+ DateUtil.dateToString(zeroDrift.getTime(), DateUtil.DATE_FULL_STR),
						mapValue + "_" + zeroDrift.getQualification());
			}
		}
		LocalDateTime localDateTime = LocalDateTime.now();
		// 每天23时剔除多余数据
		Map<String, Object> valueHasMap = null;
		if (23 == localDateTime.getHour()) {
			// 剔除缓存中48小时之前的数据
			valueHasMap = new HashMap<String, Object>();
			for (Map.Entry<String, Object> entry : valueMap.entrySet()) {
				String lastDateString = entry.getKey().substring(entry.getKey().indexOf("_") + 1);
				Date lastSingleDate = DateUtil.stringToDate(lastDateString, DateUtil.DATE_FULL_STR);
				if (lastSingleDate.after(startDate)) {
					valueHasMap.put(entry.getKey(), entry.getValue());
				}
			}
		}
		// 将缓存的数据添加到新的匹配数据中
		if (valueHasMap != null) {
			indexTimeMap.putAll(valueHasMap);
		} else {
			indexTimeMap.putAll(valueMap);
		}
		List<String> idList = new ArrayList<String>();
		// 获取站点相关信息
		Map<String, Map<String, Object>> siteMap = this.getStationMsg();
		// 获取站点配置的质控参数信息
		List<Map<String, Map<String, Object>>> allDayQualityControlParam = IQualityControlSetService
				.currentAllDayQualityControlParam();
		// 遍历封装创建零点数据
		for (int i = 0; i < list.size(); i++) {
			String id = list.get(i).getId();
			idList.add(id);
			String stationCode = list.get(i).getMn();
			String indexCode = list.get(i).getFactorCode();
			Double value = null;
			if (list.get(i).getCheckData() != null) {
				value = Double
						.valueOf(QualityDataUtil.scaleData(indexCode, Double.valueOf(list.get(i).getCheckData()))); // 测定值
			}
			String standardSamplesValue = list.get(i).getStandardValue(); // 标样值
			String spanValue = list.get(i).getSpanValue(); // 跨度值
			String qualityDisposeId = null; // 质控配置参数ID
			Date timestamp = list.get(i).getDataTime();
			boolean isRepair = false;// 判断数据是否是补传数据
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(timestamp);
			int hour = calendar.get(Calendar.HOUR_OF_DAY);
			if (hour > 6) {// 每天六点之后的数据为补传
				isRepair = true;
			}
			if ("".equals(spanValue) || "0".equals(spanValue) || spanValue == null || "0".equals(standardSamplesValue)
					|| "".equals(standardSamplesValue) || standardSamplesValue == null) { // 如果跨度值、标样值为空,则需要使用配置的跨度值参数
				for (Map<String, Map<String, Object>> map : allDayQualityControlParam) {
					Map<String, Object> indexMap = map.get(stationCode);
					if (indexMap == null) {
						continue;
					} else if ("".equals(spanValue) || "0".equals(spanValue) || spanValue == null) {
						spanValue = indexMap.get(indexCode + "spanValue") == null ? null
								: indexMap.get(indexCode + "spanValue").toString();
					} else if ("".equals(standardSamplesValue) || "0".equals(standardSamplesValue)
							|| standardSamplesValue == null) {
						standardSamplesValue = indexMap.get(indexCode + "zeroStandardValue") == null ? null
								: indexMap.get(indexCode + "zeroStandardValue").toString();
					}
					qualityDisposeId = indexMap.get(indexCode + "id") == null ? null
							: indexMap.get(indexCode + "id").toString();
					if ((!"".equals(spanValue) && !"0".equals(spanValue) && spanValue != null)
							|| (!"".equals(standardSamplesValue) && !"0".equals(standardSamplesValue)
									&& standardSamplesValue != null)) {
						break;
					}
				}
			}
			// 计算绝对误差
			String absoluteError = FLAG;
			if (value != null && standardSamplesValue != null) {
				absoluteError = QualityDataUtil.zeroCheckAbsoluteError(value, Double.valueOf(standardSamplesValue),
						indexCode);
			}
			// 计算相对误差
			String relativeError = FLAG;
			String lastDayZeroValue = FLAG;
			/**
			 * 因为补传数据会在当天12点前上传，所以不用更新补传数据之后的数据
			 */
			// 获取前一天llf
			String lastTime = DateUtil.addHour(new Date(), -24, DateUtil.DATE_SMALL_STR);
			Date todayDate = DateUtil.getTodayFirst();// 当天开始时间小时分钟秒为0
			Date lastDate = DateUtil.stringToDate(lastTime, DateUtil.DATE_SMALL_STR);
			String dataKey = stationCode + indexCode + "_" + lastTime;
			String yesterdayFlag = NO_QUALIFIED;// 上一次核查合格记录
			// 通过监测项与时间键值对找出上一天至现在相离时间最近的测定值
			if (!isRepair) {
				for (Map.Entry<String, Object> entry : indexTimeMap.entrySet()) {// 判断得到前一天最后一次质控数据
					String keyEntry = entry.getKey();
					String valueEntry = entry.getValue() == null ? FLAG : entry.getValue().toString();
					if (keyEntry.contains(dataKey)) {
						String lastDateString = keyEntry.substring(keyEntry.indexOf("_") + 1);
						Date lastSingleDate = DateUtil.stringToDate(lastDateString, DateUtil.DATE_FULL_STR);
						if (todayDate.after(lastSingleDate)
								&& (lastDate.equals(lastSingleDate) || lastDate.before(lastSingleDate))) {
							lastDate = lastSingleDate;
							if (valueEntry.contains("_")) {
								lastDayZeroValue = valueEntry.substring(0, valueEntry.indexOf("_"));
								yesterdayFlag = valueEntry.substring(valueEntry.indexOf("_") + 1);
							} else {
								lastDayZeroValue = valueEntry;
							}
							if (!FLAG.equals(lastDayZeroValue)) {
								if (value != null && spanValue != null) {
									relativeError = QualityDataUtil.zeroDriftRelativeError(value,
											Double.valueOf(lastDayZeroValue), Double.valueOf(spanValue));
								}
							}
						}
					}
				}
			}
			// 判断零点核查是否合格(绝对误差是否在技术要求之内)
			String checkQualification = NO_QUALIFIED;
			String absoluteTechnicalRequirement = "";
			if (indexCode.equals(QualityProjectEnum.IMN.getCode())) {
				if (!FLAG.equals(absoluteError)
						&& Double.valueOf(absoluteError) >= QualitySpecificationEnum.ZERO_CHECK_IMN.getLower()
						&& Double.valueOf(absoluteError) <= QualitySpecificationEnum.ZERO_CHECK_IMN.getUpper()) {
					checkQualification = QUALIFIED;
				}
				absoluteTechnicalRequirement = QualitySpecificationEnum.ZERO_CHECK_IMN.getScope();
			} else if (indexCode.equals(QualityProjectEnum.NH3.getCode())) {
				if (!FLAG.equals(absoluteError)
						&& Double.valueOf(absoluteError) >= QualitySpecificationEnum.ZERO_CHECK_NH3.getLower()
						&& Double.valueOf(absoluteError) <= QualitySpecificationEnum.ZERO_CHECK_NH3.getUpper()) {
					checkQualification = QUALIFIED;
				}
				absoluteTechnicalRequirement = QualitySpecificationEnum.ZERO_CHECK_NH3.getScope();
			} else if (indexCode.equals(QualityProjectEnum.TP.getCode())) {
				if (!FLAG.equals(absoluteError)
						&& Double.valueOf(absoluteError) >= QualitySpecificationEnum.ZERO_CHECK_TP.getLower()
						&& Double.valueOf(absoluteError) <= QualitySpecificationEnum.ZERO_CHECK_TP.getUpper()) {
					checkQualification = QUALIFIED;
				}
				absoluteTechnicalRequirement = QualitySpecificationEnum.ZERO_CHECK_TP.getScope();
			} else if (indexCode.equals(QualityProjectEnum.TN.getCode())) {
				if (!FLAG.equals(absoluteError)
						&& Double.valueOf(absoluteError) >= QualitySpecificationEnum.ZERO_CHECK_TN.getLower()
						&& Double.valueOf(absoluteError) <= QualitySpecificationEnum.ZERO_CHECK_TN.getUpper()) {
					checkQualification = QUALIFIED;
				}
				absoluteTechnicalRequirement = QualitySpecificationEnum.ZERO_CHECK_TN.getScope();
			}
			// 判断零点漂移是否合格(相对误差是否在技术要求之内)
			String driftQualification = NO_QUALIFIED;
			if (!FLAG.equals(relativeError)) {
				if (Double.valueOf(relativeError) >= QualitySpecificationEnum.ZERO_DRIFT.getLower()
						&& Double.valueOf(relativeError) <= QualitySpecificationEnum.ZERO_DRIFT.getUpper()) {
					driftQualification = QUALIFIED;
				}
				// 跨度合格条件，昨天最新一次核查合格，今天核查合格，今天跨度在误差内
				if (QUALIFIED.equals(yesterdayFlag) && QUALIFIED.equals(checkQualification)
						&& QUALIFIED.equals(driftQualification)) {
					driftQualification = QUALIFIED;
				} else {
					driftQualification = NO_QUALIFIED;
				}
			}
			// 把今天计算的核查合格情况追加到redis里面
			String dataKeyTimeAll = stationCode + indexCode + "_"
					+ DateUtil.dateToString(timestamp, DateUtil.DATE_FULL_STR);
			indexTimeMap.put(dataKeyTimeAll, value.toString() + "_" + checkQualification);
			// 初始化实体类
			ZeroDrift zeroDrift = new ZeroDrift();
			
			if (siteMap.get(stationCode) != null) {// 过滤站点未建的情况

				zeroDrift.setStationCode(stationCode);
				zeroDrift.setStationName(siteMap.get(stationCode).get("stationName").toString());
				zeroDrift.setBasinCode(siteMap.get(stationCode).get("basinn_basinnCode").toString());
				zeroDrift.setBasinName(siteMap.get(stationCode).get("basinn_basinnName").toString());
				zeroDrift.setAreaCode(siteMap.get(stationCode).get("area_areaCode").toString());
				zeroDrift.setAreaName(siteMap.get(stationCode).get("area_areaName").toString());
				zeroDrift.setOperationCode(siteMap.get(stationCode).get("operCompanyId") == null ? ""
						: siteMap.get(stationCode).get("operCompanyId").toString());
				zeroDrift.setOperationName(siteMap.get(stationCode).get("operCompanyName") == null ? ""
						: siteMap.get(stationCode).get("operCompanyName").toString());
				zeroDrift.setIndexCode(indexCode);
				zeroDrift.setIndexName(QualityProjectEnum.getName(indexCode));
				zeroDrift.setIndexUnit(QualityProjectEnum.getUnit(indexCode));
				zeroDrift.setTime(timestamp);
				zeroDrift.setValue(value == null ? "" : value.toString());
				zeroDrift.setStandardSamplesValue(standardSamplesValue.toString());
				zeroDrift.setAbsoluteError(absoluteError);
				zeroDrift.setQualification(checkQualification);
				// 获取各因子的技术标准范围
				zeroDrift.setAbsoluteTechnicalRequirement(absoluteTechnicalRequirement);
				zeroDrift.setRelativeTechnicalRequirement(QualitySpecificationEnum.ZERO_DRIFT.getScope());
				zeroDrift.setQualityDisposeId(qualityDisposeId);
				// 如果是补传的跨度数据不展示
				if (!isRepair) {
					zeroDrift.setLastValue(lastDayZeroValue);
					zeroDrift.setSpanValue(spanValue);
					zeroDrift.setLastQualification(driftQualification);
					zeroDrift.setRelativeError(relativeError);
				}
				try {
					iZeroDriftRepository.saveAndFlush(zeroDrift);
				} catch (Exception  e) {
					//e.printStackTrace();
					Throwable cause = e.getCause();
					logger.info("@@@零点漂移发生异常：" + ((org.hibernate.exception.ConstraintViolationException)cause).getSQLException().getMessage());
//					logger.info("@@@零点漂移发生异常：" + e.getLocalizedMessage()+e.toString());
				}
			}
		}
		// 每次都清空上一次缓存数据
		RedisUtil.del("zeroValueMap");
		RedisUtil.set("zeroValueMap", indexTimeMap);
		
		logger.info("@@@idList的大小" + idList.size());
		if(!idList.isEmpty()) {
			int part = idList.size() / 800; // 分批数
			logger.info("共有 ： "+idList.size()+"条");
			for (int i = 0; i <= part; i++) {
				int j = 800*(i+1);
				if(i==part) {
					j = idList.size();
				}
				logger.info("@@@开始执行updateCheckData");
				IDataReceivingService.updateCheckData(idList.subList(800*i, j));
			}
		}
		logger.info("@@@update执行结束");
	}	
		
		
			
			
			
		
	


	@SuppressWarnings("unchecked")
	@Override
	public void createSpanCheckData(String factorCode) {
		ResultEntity resultEntity = IDataReceivingService.querySpanCheckData(factorCode);
		if (resultEntity.getCode() == 1) {
			System.out.println("获取跨度核查初始数据失败！");
		}
		List<SpanCheckData> list = objectMapperUtil.convertList(resultEntity, SpanCheckData.class);
		// 先封装因子+时间,测定值的数据结构
		Map<String, Object> indexTimeMap = new HashMap<String, Object>();
		// 获取缓存数据
		Date endDate = new Date();
		Date startDate = DateUtil.addHour(endDate, -48);
		Object redisList = RedisUtil.get("spanValueMap");
		Map<String, Object> valueMap = new HashMap<String, Object>();
		if (redisList != null) {
			valueMap = (Map<String, Object>) redisList;
		} else {// 如果缓存为空则从数据库查询前一天数据
			List<SpanDrift> listSpan = iSpanDriftRepository.findByTimeBetweenOrderByTimeDesc(startDate, endDate);
			for (SpanDrift spanDrift : listSpan) {
				Double mapValue = spanDrift.getValue() == null ? null
						: QualityDataUtil.scaleData(spanDrift.getIndexCode(), Double.valueOf(spanDrift.getValue()));
				valueMap.put(
						spanDrift.getStationCode() + spanDrift.getIndexCode() + "_"
								+ DateUtil.dateToString(spanDrift.getTime(), DateUtil.DATE_FULL_STR),
						mapValue + "_" + spanDrift.getQualification());
			}
		}
		LocalDateTime localDateTime = LocalDateTime.now();
		// 每天23时剔除多余数据
		Map<String, Object> valueHasMap = null;
		if (23 == localDateTime.getHour()) {
			// 剔除缓存中48小时之前的数据
			valueHasMap = new HashMap<String, Object>();
			for (Map.Entry<String, Object> entry : valueMap.entrySet()) {
				String lastDateString = entry.getKey().substring(entry.getKey().indexOf("_") + 1);
				Date lastSingleDate = DateUtil.stringToDate(lastDateString, DateUtil.DATE_FULL_STR);
				if (lastSingleDate.after(startDate)) {
					valueHasMap.put(entry.getKey(), entry.getValue());
				}
			}
		}
		// 将缓存的数据添加到新的匹配数据中
		if (valueHasMap != null) {
			indexTimeMap.putAll(valueHasMap);
		} else {
			indexTimeMap.putAll(valueMap);
		}
		List<String> idList = new ArrayList<String>();
		// 获取站点相关信息
		Map<String, Map<String, Object>> siteMap = this.getStationMsg();
		// 获取站点配置的质控参数信息
		List<Map<String, Map<String, Object>>> allDayQualityControlParam = IQualityControlSetService
				.currentAllDayQualityControlParam();
		// 遍历封装创建跨度数据
		for (int i = 0; i < list.size(); i++) {
			String id = list.get(i).getId();
			idList.add(id);
			String stationCode = list.get(i).getMn();
			String indexCode = list.get(i).getFactorCode();
			Double value = null;
			if (list.get(i).getCheckData() != null) {
				value = Double
						.valueOf(QualityDataUtil.scaleData(indexCode, Double.valueOf(list.get(i).getCheckData()))); // 测定值
			}
			String standardSamplesValue = list.get(i).getStandardValue(); // 标样值
			String spanValue = list.get(i).getSpanValue(); // 跨度值
			String qualityDisposeId = null; // 质控配置参数ID
			Date timestamp = list.get(i).getDataTime();
			boolean isRepair = false;// 判断数据是否是补传数据
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(timestamp);
			int hour = calendar.get(Calendar.HOUR_OF_DAY);
			if (hour > 7) {// 每天七点之后的数据补传
				isRepair = true;
			}
			if ("".equals(spanValue) || "0".equals(spanValue) || spanValue == null
					|| "0.00".equals(standardSamplesValue) || "".equals(standardSamplesValue)
					|| standardSamplesValue == null) { // 如果跨度值、标样值为空,则需要使用配置的跨度值参数
				for (Map<String, Map<String, Object>> map : allDayQualityControlParam) {
					Map<String, Object> indexMap = map.get(stationCode);
					if (indexMap == null) {
						continue;
					} else if ("".equals(spanValue) || "0".equals(spanValue) || spanValue == null) {
						spanValue = indexMap.get(indexCode + "spanValue") == null ? null
								: indexMap.get(indexCode + "spanValue").toString();
					} else if ("".equals(standardSamplesValue) || "0.00".equals(standardSamplesValue)
							|| standardSamplesValue == null) {
						standardSamplesValue = indexMap.get(indexCode + "spanStandardValue") == null ? null
								: indexMap.get(indexCode + "spanStandardValue").toString();
					}
					qualityDisposeId = indexMap.get(indexCode + "id") == null ? null
							: indexMap.get(indexCode + "id").toString();
					if ((!"".equals(spanValue) && !"0".equals(spanValue) && spanValue != null)
							|| (!"".equals(standardSamplesValue) && !"0.00".equals(standardSamplesValue)
									&& standardSamplesValue != null)) {
						break;
					}
				}
			}
			// 计算核查相对误差
			String checkRelativeError = FLAG;
			if (value != null && standardSamplesValue != null) {
				checkRelativeError = QualityDataUtil.spanCheckRelativeError(value, Double.valueOf(standardSamplesValue),
						indexCode);
			}
			// 计算漂移相对误差
			String driftRelativeError = FLAG;
			String lastDaySpanValue = FLAG;
			/**
			 * 因为补传数据会在当天12点前上传，所以不用更新补传数据之后的数据
			 */
			// 获取前一天llf
			String lastTime = DateUtil.addHour(new Date(), -24, DateUtil.DATE_SMALL_STR);
			Date todayDate = DateUtil.getTodayFirst();// 当天开始时间小时分钟秒为0
			Date lastDate = DateUtil.stringToDate(lastTime, DateUtil.DATE_SMALL_STR);
			String dataKey = stationCode + indexCode + "_" + lastTime;
			String yesterdayFlag = NO_QUALIFIED;// 上一次核查合格记录
			// 通过监测项与时间键值对找出上一天至现在相离时间最近的测定值
			if (!isRepair) {
				for (Map.Entry<String, Object> entry : indexTimeMap.entrySet()) {// 判断得到前一天最后一次质控数据
					String keyEntry = entry.getKey();
					String valueEntry = entry.getValue() == null ? FLAG : entry.getValue().toString();
					if (keyEntry.contains(dataKey)) {
						String lastDateString = keyEntry.substring(keyEntry.indexOf("_") + 1);
						Date lastSingleDate = DateUtil.stringToDate(lastDateString, DateUtil.DATE_FULL_STR);
						if (todayDate.after(lastSingleDate)
								&& (lastDate.equals(lastSingleDate) || lastDate.before(lastSingleDate))) {
							lastDate = lastSingleDate;
							if (valueEntry.contains("_")) {
								lastDaySpanValue = valueEntry.substring(0, valueEntry.indexOf("_"));
								yesterdayFlag = valueEntry.substring(valueEntry.indexOf("_") + 1);
							} else {
								lastDaySpanValue = valueEntry;
							}
							if (!FLAG.equals(lastDaySpanValue)) {
								if (value != null && spanValue != null) {
									driftRelativeError = QualityDataUtil.spanDriftRelativeError(value,
											Double.valueOf(lastDaySpanValue), Double.valueOf(spanValue));
								}
							}
						}
					}
				}
			}
			// 判断跨度核查是否合格(相对误差是否在技术要求之内)
			String checkQualification = NO_QUALIFIED;
			if (!FLAG.equals(checkRelativeError)) {
				if (Double.valueOf(checkRelativeError) >= QualitySpecificationEnum.SPAN_CHECK.getLower()
						&& Double.valueOf(checkRelativeError) <= QualitySpecificationEnum.SPAN_CHECK.getUpper()) {
					checkQualification = QUALIFIED;
				}
			}
			// 判断跨度漂移是否合格(相对误差是否在技术要求之内)
			String driftQualification = NO_QUALIFIED;
			if (!FLAG.equals(driftRelativeError)) {
				if (Double.valueOf(driftRelativeError) >= QualitySpecificationEnum.SPAN_DRIFT.getLower()
						&& Double.valueOf(driftRelativeError) <= QualitySpecificationEnum.SPAN_DRIFT.getUpper()) {
					driftQualification = QUALIFIED;
				}
				// 跨度合格条件，昨天最新一次核查合格，今天核查合格，今天跨度在误差内
				if (QUALIFIED.equals(yesterdayFlag) && QUALIFIED.equals(checkQualification)
						&& QUALIFIED.equals(driftQualification)) {
					driftQualification = QUALIFIED;
				} else {
					driftQualification = NO_QUALIFIED;
				}
			}
			// 讲今天的数据及合格情况追加到redis
			String dataKeyTimeAll = stationCode + indexCode + "_"
					+ DateUtil.dateToString(timestamp, DateUtil.DATE_FULL_STR);
			indexTimeMap.put(dataKeyTimeAll, value.toString() + "_" + checkQualification);
			// 初始化实体类
			SpanDrift spanDrift = new SpanDrift();
			
			if(siteMap.get(stationCode)!=null) {//过滤站点未建的情况
				spanDrift.setStationCode(stationCode);
				spanDrift.setStationName(siteMap.get(stationCode).get("stationName").toString());
				spanDrift.setBasinCode(siteMap.get(stationCode).get("basinn_basinnCode").toString());
				spanDrift.setBasinName(siteMap.get(stationCode).get("basinn_basinnName").toString());
				spanDrift.setAreaCode(siteMap.get(stationCode).get("area_areaCode").toString());
				spanDrift.setAreaName(siteMap.get(stationCode).get("area_areaName").toString());
				spanDrift.setOperationCode(siteMap.get(stationCode).get("operCompanyId") == null ? ""
						: siteMap.get(stationCode).get("operCompanyId").toString());
				spanDrift.setOperationName(siteMap.get(stationCode).get("operCompanyName") == null ? ""
						: siteMap.get(stationCode).get("operCompanyName").toString());
				spanDrift.setIndexCode(indexCode);
				spanDrift.setIndexName(QualityProjectEnum.getName(indexCode));
				spanDrift.setIndexUnit(QualityProjectEnum.getUnit(indexCode));
				spanDrift.setTime(timestamp);
				spanDrift.setValue(value.toString());
				spanDrift.setStandardSamplesValue(standardSamplesValue.toString());
				spanDrift.setCheckRelativeError(checkRelativeError);
				spanDrift.setQualification(checkQualification);
				spanDrift.setDriftRelativeError(driftRelativeError);
				spanDrift.setCheckTechnicalRequirement(QualitySpecificationEnum.SPAN_CHECK.getScope());
				spanDrift.setDriftTechnicalRequirement(QualitySpecificationEnum.SPAN_DRIFT.getScope());
				spanDrift.setQualityDisposeId(qualityDisposeId);
				// 如果是补传的跨度数据不展示
				if (!isRepair) {
					spanDrift.setLastValue(lastDaySpanValue);
					spanDrift.setSpanValue(spanValue);
					spanDrift.setLastQualification(driftQualification);
				}
				try {
					iSpanDriftRepository.saveAndFlush(spanDrift);
				} catch (Exception e) {
					Throwable cause = e.getCause();
					logger.info("@@@跨度漂移发生异常：" + ((org.hibernate.exception.ConstraintViolationException)cause).getSQLException().getMessage());
				}
			}
			
		}
		// 每次都清空上一次缓存数据
		RedisUtil.del("spanValueMap");
		// 设置缓存(是将list数据保存至缓存中的list中,故上述取值时取list中第一个)
		RedisUtil.set("spanValueMap", indexTimeMap);
		
		logger.info("@@@idList的大小" + idList.size());
		if(!idList.isEmpty()) {
			int part = idList.size() / 800; // 分批数
			logger.info("共有 ： "+idList.size()+"条");
			for (int i = 0; i <= part; i++) {
				int j = 800*(i+1);
				if(i==part) {
					j = idList.size();
				}
				logger.info("@@@开始执行updateSpanCheckData");
				IDataReceivingService.updateSpanCheckData(idList.subList(800*i, j));
			}
			logger.info("@@@update执行结束");		
		}
	}

	@Override
	public void createRecoveryData() {
		// 获取站点相关信息
		Map<String, Map<String, Object>> siteMap = this.getStationMsg();
		// 获取站点配置的质控参数信息
		List<Map<String, Map<String, Object>>> allMonthQualityControlRecoveryParam = IQualityControlSetService
				.currentMonthQualityControlRecoveryParam();
		ResultEntity resultEntity = IDataReceivingService.queryRecoveryData();
		if (resultEntity.getCode() == 1) {
			System.out.println("获取加标回收率初始数据失败！");
		}
		List<RecoveryData> list = objectMapperUtil.convertList(resultEntity, RecoveryData.class);
		List<String> idList = new ArrayList<String>();
		for (RecoveryData recoveryData : list) {
			String id = recoveryData.getId();
			idList.add(id);
			String stationCode = recoveryData.getMn();
			String indexCode = recoveryData.getFactorCode();
			String value = recoveryData.getWater(); // 测定值
			String addValue = recoveryData.getCheckData(); // 加标后水样测定值
			String addVolume = recoveryData.getVolume(); // 加标体积
			String addConcentration = recoveryData.getChromaValue(); // 加标浓度
			String waterSampleVolume = recoveryData.getDVolume(); // 加标后体积
			Date timestamp = recoveryData.getDataTime(); // 测试时间
			for (Map<String, Map<String, Object>> map : allMonthQualityControlRecoveryParam) {
				Map<String, Object> indexMap = map.get(stationCode);
				if (indexMap == null) {
					continue;
				}
				addConcentration = indexMap.get(indexCode + "addConcentration") == null ? null
						: indexMap.get(indexCode + "addConcentration").toString();
				waterSampleVolume = indexMap.get(indexCode + "constantVolume") == null ? null
						: indexMap.get(indexCode + "constantVolume").toString();
				if ((!"".equals(addConcentration) && addConcentration != null)
						|| (!"".equals(waterSampleVolume) && waterSampleVolume != null)) {
					break;
				}
			}
			// 计算加标回收率
			String recoveryValue = FLAG;
			if (value != null && addValue != null && addVolume != null && addConcentration != null
					&& waterSampleVolume != null) {
				recoveryValue = QualityDataUtil.standardRecoveryRate(Double.valueOf(addValue), Double.valueOf(value),
						Double.valueOf(addVolume), Double.valueOf(addConcentration), Double.valueOf(waterSampleVolume));
			}
			// 判断是否合格
			String qualification = NO_QUALIFIED;
			if (!FLAG.equals(recoveryValue)) {
				if (Double.valueOf(recoveryValue) >= QualitySpecificationEnum.RECOVERY.getLower()
						&& Double.valueOf(recoveryValue) <= QualitySpecificationEnum.RECOVERY.getUpper()) {
					qualification = QUALIFIED;
				}
			}
			Recovery recovery = new Recovery();

			if(siteMap.get(stationCode)!=null) {//过滤站点未建的情况				
				recovery.setStationCode(stationCode);
				recovery.setStationName(siteMap.get(stationCode).get("stationName").toString());
				recovery.setBasinCode(siteMap.get(stationCode).get("basinn_basinnCode").toString());
				recovery.setBasinName(siteMap.get(stationCode).get("basinn_basinnName").toString());
				recovery.setAreaCode(siteMap.get(stationCode).get("area_areaCode").toString());
				recovery.setAreaName(siteMap.get(stationCode).get("area_areaName").toString());
				recovery.setOperationCode(siteMap.get(stationCode).get("operCompanyId") == null ? ""
						: siteMap.get(stationCode).get("operCompanyId").toString());
				recovery.setOperationName(siteMap.get(stationCode).get("operCompanyName") == null ? ""
						: siteMap.get(stationCode).get("operCompanyName").toString());
				recovery.setIndexCode(indexCode);
				recovery.setIndexName(QualityProjectEnum.getName(indexCode));
				recovery.setIndexUnit(QualityProjectEnum.getUnit(indexCode));
				recovery.setTime(timestamp);
				recovery.setValue(value);
				recovery.setAddValue(addValue);
				recovery.setAddConcentration(addConcentration);
				recovery.setAddVolume(addVolume);
				recovery.setWaterSampleVolume(waterSampleVolume);
				recovery.setRecoveryValue(recoveryValue);
				recovery.setError(recoveryValue);
				recovery.setTechnicalRequirement(QualitySpecificationEnum.RECOVERY.getScope());
				recovery.setQualification(qualification);
				try {
					iRecoveryRepository.saveAndFlush(recovery);
				} catch (Exception e) {
					Throwable cause = e.getCause();
					logger.info("@@@recovery漂移发生异常：" + ((org.hibernate.exception.ConstraintViolationException)cause).getSQLException().getMessage());
				}
			}
		}
		
		logger.info("@@@idList的大小" + idList.size());
		if(!idList.isEmpty()) {
			int part = idList.size() / 800; // 分批数
			logger.info("共有 ： "+idList.size()+"条");
			for (int i = 0; i <= part; i++) {
				int j = 800*(i+1);
				if(i==part) {
					j = idList.size();
				}
				logger.info("@@@开始执行updateRecoveryData");
				IDataReceivingService.updateRecoveryData(idList.subList(800*i, j));
			}
			logger.info("@@@update执行结束");
		}
	}

	@Override
	public void createCheckData() {
		// 获取站点相关信息
		Map<String, Map<String, Object>> siteMap = this.getStationMsg();
		// 获取站点配置的质控参数信息
		List<Map<String, Map<String, Object>>> allMonthQualityControlStandardParam = IQualityControlSetService
				.currentMonthQualityControlStandardCheckParam();
		ResultEntity resultEntity = IDataReceivingService.queryCheckData();
		if (resultEntity.getCode() == 1) {
			System.out.println("获取标样初始数据失败！");
		}
		List<CheckData> list = objectMapperUtil.convertList(resultEntity, CheckData.class);
		List<String> idList = new ArrayList<String>();
		for (CheckData checkData : list) {
			String id = checkData.getId();
			idList.add(id);
			String stationCode = checkData.getMn();
			String indexCode = checkData.getFactorCode();
			String dataFlag = checkData.getFlag();
			Double value = null;
			if (checkData.getCheckData() != null) {
				value = Double.valueOf(checkData.getCheckData()); // 测定值
			}
			String standardSamplesValue = null;
			if (checkData.getStandardValue() != null) {
				standardSamplesValue = checkData.getStandardValue(); // 标样标准浓度值
			} else {
				for (Map<String, Map<String, Object>> map : allMonthQualityControlStandardParam) {
					Map<String, Object> indexMap = map.get(stationCode);
					if (indexMap == null) {
						continue;
					}
					standardSamplesValue = indexMap.get(indexCode) == null ? null : indexMap.get(indexCode).toString();
					if (!"".equals(standardSamplesValue) && standardSamplesValue != null) {
						break;
					}
				}
			}
			Date timestamp = checkData.getDataTime();
			if (!"w01010".equals(indexCode)) {
				// 计算误差
				String error = FLAG;
				if (value != null && standardSamplesValue != null) {
					error = QualityDataUtil.verificationOfStandardSamplesError(value,
							Double.valueOf(standardSamplesValue), indexCode);
				}
				// 判断是否合格及对应的技术标准
				String qualification = NO_QUALIFIED;
				String technicalRequirement = "-";
				if (indexCode.equals(QualityProjectEnum.PH.getCode())) {
					if (!FLAG.equals(error)
							&& Double.valueOf(error) >= QualitySpecificationEnum.STANDARD_CHECK_PH.getLower()
							&& Double.valueOf(error) <= QualitySpecificationEnum.STANDARD_CHECK_PH.getUpper()) {
						qualification = QUALIFIED;
					}
					technicalRequirement = QualitySpecificationEnum.STANDARD_CHECK_PH.getScope();
				} else if (indexCode.equals(QualityProjectEnum.DO.getCode())) {
					if (!FLAG.equals(error)
							&& Double.valueOf(error) >= QualitySpecificationEnum.STANDARD_CHECK_DO.getLower()
							&& Double.valueOf(error) <= QualitySpecificationEnum.STANDARD_CHECK_DO.getUpper()) {
						qualification = QUALIFIED;
					}
					technicalRequirement = QualitySpecificationEnum.STANDARD_CHECK_DO.getScope();
				} else if (indexCode.equals(QualityProjectEnum.EC.getCode())) {
					if (Double.valueOf(standardSamplesValue) > 100) {
						if (!FLAG.equals(error)
								&& Double.valueOf(error) >= QualitySpecificationEnum.STANDARD_CHECK_EC_GR.getLower()
								&& Double.valueOf(error) <= QualitySpecificationEnum.STANDARD_CHECK_EC_GR.getUpper()) {
							qualification = QUALIFIED;
						}
						technicalRequirement = QualitySpecificationEnum.STANDARD_CHECK_EC_GR.getScope();
					} else {
						if (!FLAG.equals(error)
								&& Double.valueOf(error) >= QualitySpecificationEnum.STANDARD_CHECK_EC_LE.getLower()
								&& Double.valueOf(error) <= QualitySpecificationEnum.STANDARD_CHECK_EC_LE.getUpper()) {
							qualification = QUALIFIED;
						}
						technicalRequirement = QualitySpecificationEnum.STANDARD_CHECK_EC_LE.getScope();
					}
				} else if (indexCode.equals(QualityProjectEnum.TUB.getCode())) {
					if (!FLAG.equals(error)
							&& Double.valueOf(error) >= QualitySpecificationEnum.STANDARD_CHECK_TUB.getLower()
							&& Double.valueOf(error) <= QualitySpecificationEnum.STANDARD_CHECK_TUB.getUpper()) {
						qualification = QUALIFIED;
					}
					technicalRequirement = QualitySpecificationEnum.STANDARD_CHECK_TUB.getScope();
				}
				VerificationOfStandardSample verificationOfStandardSample = new VerificationOfStandardSample();
				

				if(siteMap.get(stationCode)!=null) {//过滤站点未建的情况					
					verificationOfStandardSample.setStationCode(stationCode);
					verificationOfStandardSample.setStationName(siteMap.get(stationCode).get("stationName").toString());
					verificationOfStandardSample.setBasinCode(siteMap.get(stationCode).get("basinn_basinnCode").toString());
					verificationOfStandardSample.setBasinName(siteMap.get(stationCode).get("basinn_basinnName").toString());
					verificationOfStandardSample.setAreaCode(siteMap.get(stationCode).get("area_areaCode").toString());
					verificationOfStandardSample.setAreaName(siteMap.get(stationCode).get("area_areaName").toString());
					verificationOfStandardSample.setOperationCode(siteMap.get(stationCode).get("operCompanyId") == null ? ""
							: siteMap.get(stationCode).get("operCompanyId").toString());
					verificationOfStandardSample
					.setOperationName(siteMap.get(stationCode).get("operCompanyName") == null ? ""
							: siteMap.get(stationCode).get("operCompanyName").toString());
					verificationOfStandardSample.setIndexCode(indexCode);
					verificationOfStandardSample.setIndexName(QualityProjectEnum.getName(indexCode));
					verificationOfStandardSample.setIndexUnit(QualityProjectEnum.getUnit(indexCode));
					verificationOfStandardSample.setTime(timestamp);
					verificationOfStandardSample.setValue(value.toString());
					verificationOfStandardSample.setStandardSamplesValue(standardSamplesValue.toString());
					verificationOfStandardSample.setError(error);
					verificationOfStandardSample.setTechnicalRequirement(technicalRequirement);
					verificationOfStandardSample.setQualification(qualification);
					verificationOfStandardSample.setDataFlag(dataFlag);
					try {
						iVerificationOfStandardSampleRepository.saveAndFlush(verificationOfStandardSample);
					} catch (Exception e) {
						Throwable cause = e.getCause();
						logger.info("@@@标样核查发生异常：" + ((org.hibernate.exception.ConstraintViolationException)cause).getSQLException().getMessage());
					}
				}
			}
		}
		logger.info("@@@idList的大小" + idList.size());
		if(!idList.isEmpty()) {
			int part = idList.size() / 800; // 分批数
			logger.info("共有 ： "+idList.size()+"条");
			for (int i = 0; i <= part; i++) {
				int j = 800*(i+1);
				if(i==part) {
					j = idList.size();
				}
				logger.info("@@@开始执行updateCheckData");
				IDataReceivingService.updateCheckData(idList.subList(800*i, j));
			}
			logger.info("@@@update执行结束");
		}
	}

	@SuppressWarnings("unchecked")
	public Map<String, Map<String, Object>> getStationMsg() {
		QueryParamDto queryParamDto = null;
		try {
			queryParamDto = JsonUtils.readJsonFromClassPath("/queryParam/siteQuery.json", QueryParamDto.class);
		} catch (IOException e) {
			e.printStackTrace();
		}
		ResultEntity resultEntity = ISiteManageService.queryStation(queryParamDto);
		Map<String, Object> dataMap = (Map<String, Object>) resultEntity.getContent();
		List<Map<String, Object>> siteList = (List<Map<String, Object>>) dataMap.get("dataList");
		Map<String, Map<String, Object>> siteMap = new HashMap<>();
		for (Map<String, Object> map : siteList) {
			siteMap.put(map.get("stationMn").toString(), map);
		}
		return siteMap;
	}

}
